package com.ph.controller;

import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.BeanUtils;
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
import org.springframework.web.bind.annotation.ResponseBody;

import com.alibaba.dubbo.config.annotation.Reference;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.JSONObject;
import com.ph.constant.LoginConstant;
import com.ph.constant.PsResultEnum;
import com.ph.custom.annotation.MemberCache;
import com.ph.custom.annotation.Token;
import com.ph.custom.cache.CacheContent;
import com.ph.custom.cenum.TokenCheckEnum;
import com.ph.custom.cenum.UserCacheEnum;
import com.ph.entity.LoginCallBackData;
import com.ph.entity.MemberInfo;
import com.ph.shopping.common.core.customenum.ResultEnum;
import com.ph.shopping.common.core.customenum.SmsCodeType;
import com.ph.shopping.common.util.other.PhoneFormatCheckUtils;
import com.ph.shopping.common.util.result.Result;
import com.ph.shopping.common.util.verifycode.VerifycodeUtils;
import com.ph.shopping.facade.member.dto.MemberLoginDto;
import com.ph.shopping.facade.member.dto.MemberPasswordDto;
import com.ph.shopping.facade.member.dto.RegisterMemberDto;
import com.ph.shopping.facade.member.entity.Member;
import com.ph.shopping.facade.member.service.IMemberService;
import com.ph.shopping.facade.member.service.ISmsCodeSendService;
import com.ph.shopping.facade.member.vo.MemberLoginVo;
import com.ph.shopping.facade.member.vo.PasswordVo;
import com.ph.util.BackParamHandleUtil;
import com.ph.util.ResultUtil;
/**
 * 
 * @ClassName:  LoginAndRegController   
 * @Description:会员相关action   
 * @author: lijie
 * @date:   2017年4月17日 上午10:04:09     
 * @Copyright: 2017
 */
@Controller
@RequestMapping("member")
public class LoginAndRegController {

	private static final Logger logger = LoggerFactory.getLogger(LoginAndRegController.class);
	 
	@Reference(version="1.0.0")
	private IMemberService memberService;
	
	/**
	 * 短信服务
	 */
	@Reference(version="1.0.0")
	private ISmsCodeSendService smsCodeSendService;
	
	/**
	 * 
	* @Title: login  
	* @Description: 加载会员登录 页面 
	* @param @param request
	* @param @return    参数  
	* @return String    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadlogin")
	public String loadlogin(HttpServletRequest request, Model model, String callBackData) {
		logger.info("加载会员登录 页面 callBackData : " + callBackData);
		try {
			if (StringUtils.isNotBlank(callBackData)) {
				LoginCallBackData data = getCallBackData(callBackData);
				if(data != null){
					String type = data.getJumpType();
					if (LoginConstant.REQUEST_GET.equalsIgnoreCase(type)) {
						model.addAttribute("callBackByGet", BackParamHandleUtil.jumpPackBack(data));
					} else if (LoginConstant.REQUEST_POST.equalsIgnoreCase(type)) {
						model.addAttribute("callBackByPost", BackParamHandleUtil.jumpPackBack(data));
					}
				}
			}
		} catch (Exception e) {
			logger.error("加载会员登录 页面 错误", e);
		}
		return "loginAndReg/login";
	}
	/**
	 * 
	 * @Title: getCallBackData   
	 * @Description: 处理回调参数   
	 * @param: @param data
	 * @param: @return      
	 * @return: LoginCallBackData      
	 * @throws
	 */
	private LoginCallBackData getCallBackData(String data){
		LoginCallBackData callBackData = null;
		try {
			callBackData = JSONObject.parseObject(data, LoginCallBackData.class);
		} catch (Exception e) {
			logger.error("解析登录回调参数错误",e);
		}
		return callBackData;
	}
	/**
	 * 
	* @Title: loadregister  
	* @Description:加载注册页面)  
	* @param @param request
	* @param @return    参数  
	* @return String    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadRegister", method = RequestMethod.GET)
	public String loadregister() {

		return "loginAndReg/register";
	}
	/**
	 * 
	* @Title: loadRegisterPrompt  
	* @Description: 注册成功提示页面 
	* @param @return    参数  
	* @return String    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadRegisterPrompt", method = RequestMethod.GET)
	public String loadRegisterPrompt() {

		return "loginAndReg/registerPrompt";
	}
	/**
	 * 
	* @Title: loadRetrievePassword  
	* @Description: 找回密码页面  
	* @param @return    参数  
	* @return String    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadRetrievePassword", method = RequestMethod.GET)
	public String loadRetrievePassword() {

		return "loginAndReg/retrievePassword";
	}
	/**
	 * 
	* @Title: loadRetrievePrompt  
	* @Description:找回密码提示页面 
	* @param @return    参数  
	* @return String    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadRetrievePrompt", method = RequestMethod.GET)
	public String loadRetrievePrompt() {

		return "loginAndReg/retrievePrompt";
	}
	/**
	 * 
	* @Title: loadVerifyCode  
	* @Description: 加载验证码 
	* @param @param request
	* @param @param response    参数  
	* @return void    返回类型  
	* @throws
	 */
	@RequestMapping(value = "/loadverify" ,method = RequestMethod.GET)
	public void loadVerifyCode(HttpServletRequest request,HttpServletResponse response){
		
		VerifycodeUtils.makeVerifyImageByNum(request, response,4);
	}
	/**
	 * 
	* @Title: loginsubmit  
	* @Description: 登录处理操作  
	* @param @param member
	* @param @return    参数  
	* @return Map<String,Object>    返回类型  
	* @throws
	 */
	@RequestMapping("/loginsubmit")
	@ResponseBody
	@MemberCache(userCache = { UserCacheEnum.INSERT })
	public Map<String, Object> loginsubmit(HttpServletRequest request,MemberInfo memberInfo,MemberLoginVo member) {
		logger.info("登录处理参数：MemberLoginVo = {} ", JSON.toJSONString(member));
		Map<String, Object> map = ResultUtil.setResult(false, PsResultEnum.FAIL.getMsg());
		try {
			if (member != null) {
				String verifyCode = member.getVerifyCode();
				String secode = VerifycodeUtils.getVerifyCodeBySession(request);

				if (verifyCode == null || !verifyCode.equalsIgnoreCase(secode)) {
					ResultUtil.setResult(map, false, "验证码错误");
					return map;
				}
				MemberLoginDto dto = new MemberLoginDto();
				dto.setPhone(member.getAccountNumber());
				dto.setPassword(member.getPassword());
				Result result = memberService.memberLogin(dto);
				logger.info("登录返回数据：Result = {} ", JSON.toJSONString(result));
				if (result != null) {
					String code = result.getCode();
					if (ResultEnum.SUCCESS.getCode().equals(code)) {
						Object data = result.getData();
						if (data instanceof Member) {
							BeanUtils.copyProperties(data, memberInfo);
						}
						ResultUtil.setResult(map, true, "登录成功");
					} else if (ResultEnum.MEMBER_USER_MISMATCH.getCode().equals(code)) {
						ResultUtil.setResult(map, false, ResultEnum.MEMBER_USER_MISMATCH.getMsg());
					} else if (ResultEnum.MEMBER_PWD_MISMATCH.getCode().equals(code)) {
						ResultUtil.setResult(map, false, ResultEnum.MEMBER_PWD_MISMATCH.getMsg());
					} else if (ResultEnum.MEMBER_FROZEN.getCode().equals(code)) {
						ResultUtil.setResult(map, false, ResultEnum.MEMBER_FROZEN.getMsg());
					}
				}
			}
		} catch (Exception e) {
			logger.error("登录处理错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}

	/**
	 * 
	 * @Title: registersubmit   
	 * @Description: 注册   
	 * @param: @param request
	 * @param: @param member
	 * @param: @return      
	 * @return: Map<String,Object>      
	 * @throws
	 */
	@Token(errorDesc = "验证码超时")
	@ResponseBody
	@RequestMapping("/registersubmit")
	public Map<String, Object> registersubmit(HttpServletRequest request, MemberLoginVo member) {
		logger.info("注册处理参数：MemberLoginVo = {} ", JSON.toJSONString(member));
		Map<String, Object> map = ResultUtil.setResult(false, PsResultEnum.FAIL.getMsg());
		try {
			if (member != null) {
				Member meber = new Member();
				meber.setMemberPhone(member.getAccountNumber());
				meber.setMemberPwd(member.getPassword());
				RegisterMemberDto dto = new RegisterMemberDto();
				dto.setMeber(meber);
				Result result = memberService.registerMember(dto);
				logger.info("注册返回数据：Result = {} ", JSON.toJSONString(result));
				if (result != null) {
					String code = result.getCode();
					if (ResultEnum.SUCCESS.getCode().equals(code)) {
						ResultUtil.setResult(map, true, "注册成功");
					} else if (ResultEnum.MEMBER_DATA_EXISTS.getCode().equals(code)) {
						ResultUtil.setResult(map, false, "会员已存在");
					}
				}
			}
		} catch (Exception e) {
			logger.error("注册处理错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}
	/**
	 * 
	* @Title: verifySmsCode  
	* @Description: 根据手机号获取短信验证码  
	* @param @param request
	* @param @param phone
	* @param @param smsCode
	* @param @return    参数  
	* @return Map<String,Object>    返回类型  
	* @throws
	 */
	@RequestMapping("/verifySmsCode")
	@ResponseBody
	public Map<String, Object> verifySmsCode(HttpServletRequest request, String phone, String smsCode) {
		logger.info("根据手机号获取短信验证码 phone: " + phone + " smsCode : " + smsCode);
		Map<String, Object> map = ResultUtil.setResult(false, "验证码错误");
		try {
			Result result = smsCodeSendService.verifySmsCode(phone, SmsCodeType.SEND_SMSCODE.getCodeType(), smsCode);
			logger.info("根据手机号获取短信验证码返回数据 Result = {} ", JSON.toJSONString(result));
			if (result != null) {
				String code = result.getCode();
				if (ResultEnum.SUCCESS.getCode().equals(code)) {
					ResultUtil.setResult(map, true, "发送成功");
				} else if (ResultEnum.MEMBER_NO_DATA.getCode().equals(code)) {
					ResultUtil.setResult(map, false, "验证码失效");
				}
			}
		} catch (Exception e) {
			logger.error("根据手机号获取短信验证码错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}
	/***
	 * 
	* @Title: sendSmsCode  
	* @Description: 发送短信验证码  
	* @param @param request
	* @param @param phone
	* @param @return    参数  
	* @return Map<String,Object>    返回类型  
	* @throws
	 */
	@Token(tokenCache = { TokenCheckEnum.PUT })
	@RequestMapping("/sendSmsCode")
	@ResponseBody
	public Map<String, Object> sendSmsCode(HttpServletRequest request, String phone,CacheContent<String, String> tokenCache) {
		logger.info("发送短信验证码 phone: " + phone);
		Map<String, Object> map = ResultUtil.setResult(false, PsResultEnum.FAIL.getMsg());
		try {
			Result result = smsCodeSendService.sendSmsCodeByNoMsg(phone, SmsCodeType.SEND_SMSCODE.getCodeType());
			logger.info("发送短信验证码 返回数据 Result = {} ", JSON.toJSONString(result));
			if (result != null) {
				if (ResultEnum.SUCCESS.getCode().equals(result.getCode())) {
					map.put(tokenCache.getName(), tokenCache.getContent());
					ResultUtil.setResult(map, true, "检验成功");
				} else {
					map.put("message", result.getMessage());
				}
			}
		} catch (Exception e) {
			logger.error("发送短信验证码 错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}
	/**
	 * 
	* @Title: backPwdSubmit  
	* @Description: 找回密码  
	* @param @param request
	* @param @param member
	* @param @return    参数  
	* @return Map<String,Object>    返回类型  
	* @throws
	 */
	@Token(errorDesc = "验证码超时")
	@ResponseBody
	@RequestMapping("/backPwdSubmit")
	public Map<String, Object> backPwdSubmit(HttpServletRequest request, PasswordVo pv) {
		logger.info("找回密码处理参数：PasswordVo = {} ", JSON.toJSONString(pv));
		Map<String, Object> map = ResultUtil.setResult(false, PsResultEnum.FAIL.getMsg());
		try {
			if (pv != null) {
				MemberPasswordDto dto = new MemberPasswordDto();
				dto.setMemberPhone(pv.getPhone());
				dto.setNewPassword(pv.getNewPwd());
				Result result = memberService.backMmberPassword(dto);
				logger.info("找回密码返回数据：Result = {} ", JSON.toJSONString(result));
				if (result != null) {
					String code = result.getCode();
					if (ResultEnum.SUCCESS.getCode().equals(code)) {
						ResultUtil.setResult(map, true, "找回密码成功");
					} else if (ResultEnum.MEMBERUSER_NON_EXISTENT.getCode().equals(code)) {
						ResultUtil.setResult(map, false, "会员不存在");
					} else if (ResultEnum.MEMBER_FROZEN.getCode().equals(code)) {
						ResultUtil.setResult(map, false, ResultEnum.MEMBER_FROZEN.getMsg());
					}
				}
			}
		} catch (Exception e) {
			logger.error("找回密码处理错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}
	/**
	 * 
	 * @Title: checkPhone   
	 * @Description: 校验手机号 判断是否存在
	 * @param: @param request
	 * @param: @param phone
	 * @param: @return      
	 * @return: Map<String,Object>      
	 * @throws
	 */
	@ResponseBody
	@RequestMapping("/checkPhone")
	public Map<String, Object> checkPhone(HttpServletRequest request, String phone) {
		logger.info("验证账号是否存在：phone = {} ", phone);
		Map<String, Object> map = ResultUtil.setResult(false, PsResultEnum.FAIL.getMsg());
		try {
			// 校验手机号格式 防止非法调用
			if (!PhoneFormatCheckUtils.isPhoneLegal(phone)) {
				logger.warn("checkPhone 手机号格式错误");
				ResultUtil.setResult(false, "手机号格式错误！");
			} else {
				Result result = memberService.verifyPhoneIsExists(phone);
				logger.info("根据手机号获取会员信息返回数据：Result = {} ", JSON.toJSONString(result));
				if (result != null) {
					if (ResultEnum.SUCCESS.getCode().equals(result.getCode())) {
						ResultUtil.setResult(map, true, "");
					}
				}
			}
		} catch (Exception e) {
			logger.error("验证账号是否存在错误", e);
			ResultUtil.setResult(map, false, "服务器繁忙请稍后再试");
		}
		return map;
	}
	/**
	 * 
	 * @Title: removeUserCache   
	 * @Description: 清楚缓存  
	 * @param: @param request
	 * @param: @return      
	 * @return: Map<String,Object>      
	 * @throws
	 */
	@RequestMapping("/removeUserCache")
	@ResponseBody
	@MemberCache(userCache = { UserCacheEnum.DELETE })
	public Map<String, Object> removeUserCache(HttpServletRequest request) {

		return ResultUtil.setResult(true, "清楚缓存成功");
	}
	/**
	 * 
	* @Title: cancellLogin  
	* @Description: 注销
	* @param @param request
	* @param @return    参数  
	* @return Map<String,Object>    返回类型  
	* @throws
	 */
	@RequestMapping("/logout")
	@MemberCache(userCache = { UserCacheEnum.DELETE })
	public void logout(HttpServletRequest request,HttpServletResponse response) {
		try {
			response.sendRedirect("/member/loadlogin");
		} catch (Exception e) {
			logger.error("注销登录处理错误", e);
		}
	}
}
